package com.adopapa.nezhacloud.authc.service;

import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import java.util.Optional;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort.Order;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;

import com.adopapa.nezhacloud.authc.domain.ResourcePerm;
import com.adopapa.nezhacloud.authc.domain.ResourcePermRepository;
import com.adopapa.nezhacloud.authc.domain.RoleInfo;
import com.adopapa.nezhacloud.common.Tools;
import com.adopapa.nezhacloud.ddd.service.BaseDomainService;

import jakarta.persistence.criteria.CriteriaBuilder;
import jakarta.persistence.criteria.CriteriaQuery;
import jakarta.persistence.criteria.Predicate;
import jakarta.persistence.criteria.Root;

@Service
public class ResourcePermService extends BaseDomainService<ResourcePerm> {

	@Autowired
	private ResourcePermRepository resourcePermRepository;

	public ResourcePerm getResourcePermById(String id) {
		Optional<ResourcePerm> optional = resourcePermRepository.findById(id);
		return optional.isPresent() ? optional.get() : null;
	}
	
	public List<ResourcePerm> getResourcePermByRoleInfo(RoleInfo roleInfo) {
		return resourcePermRepository.findByRoleInfo(roleInfo);
	}

	public Page<ResourcePerm> getResourcePermPage(int pageNo, int pageSize, ResourcePerm resourcePerm) {
		PageRequest pageRequest = buildPageRequest(pageNo, pageSize, Order.desc("createTime"));
		Specification<ResourcePerm> specification = buildSpecification(resourcePerm);
		Page<ResourcePerm> page = resourcePermRepository.findAll(specification, pageRequest);
		return page;
	}

	public ResourcePerm saveResourcePerm(ResourcePerm resourcePerm) {
		return resourcePermRepository.saveAndFlush(resourcePerm);
	}

	public List<ResourcePerm> saveResourcePerms(List<ResourcePerm> resourcePerms) {
		return resourcePermRepository.saveAllAndFlush(resourcePerms);
	}

	public void deleteResourcePerm(String id) {
		resourcePermRepository.deleteById(id);
	}

	public void deleteResourcePerm(ResourcePerm resourcePerm) {
		resourcePermRepository.delete(resourcePerm);
	}

	public void deleteResourcePerms(String... ids) {
		resourcePermRepository.deleteAllByIdInBatch(Arrays.asList(ids));
	}

	public void deleteResourcePerms(List<ResourcePerm> resourcePerms) {
		resourcePermRepository.deleteAllInBatch(resourcePerms);
	}

	@SuppressWarnings("serial")
	@Override
	public Specification<ResourcePerm> buildSpecification(ResourcePerm resourcePerm) {
		return new Specification<ResourcePerm>() {
			@Override
			public Predicate toPredicate(Root<ResourcePerm> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
				List<Predicate> predicates = new LinkedList<>();
				if (!Tools.empty(resourcePerm.getRoleInfo())//
						&& !Tools.empty(resourcePerm.getRoleInfo().getId())) {
					predicates.add(cb.equal(root.join("roleInfo").get("id"), //
							resourcePerm.getRoleInfo().getId()));
				}
				if (!Tools.empty(resourcePerm.getResourceInfo())//
						&& !Tools.empty(resourcePerm.getResourceInfo().getId())) {
					predicates.add(cb.equal(root.join("resourceInfo").get("id"), //
							resourcePerm.getResourceInfo().getId()));
				}
				return cb.and(predicates.toArray(new Predicate[0]));
			}

		};
	}

	// predicates.add(cb.equal(cb.substring(root.get("datagram"), 1, 23),
	// dataPrefix));

}
